// threadtest.cc 
//	Simple test case for the threads assignment.
//
//	Create two threads, and have them context switch
//	back and forth between themselves by calling Thread::Yield, 
//	to illustratethe inner workings of the thread system.
//
// Copyright (c) 1992-1993 The Regents of the University of California.
// All rights reserved.  See copyright.h for copyright notice and limitation 
// of liability and disclaimer of warranty provisions.

#include "copyright.h"
#include "system.h"
#include "synch.h"

//#include "stdlib.h"

//----------------------------------------------------------------------
// SimpleThread
// 	Loop 5 times, yielding the CPU to another ready thread 
//	each iteration.
//
//	"which" is simply a number identifying the thread, for debugging
//	purposes.
//----------------------------------------------------------------------

// T2 vars
Semaphore **chopsticks;
Semaphore *eatSem = new Semaphore("Eat This", 1);
int philos;
bool *didSit;
bool *didEat;
bool *isEating;
bool *didStand;
bool doneEating = false;
bool didAnnounce = false;
bool proceed2 = true;
bool proceed = false;
bool everyoneUp = false;
int numSat = 0;

// T3 vars
bool critical = false;
int threePhils;
bool *didSitThree;
bool *didEatThree;
bool *isEatingThree;
bool *didStandThree;
bool *chopsThree;
bool doneEatingThree = false;
int numSatThree = 0;
bool proceedThree = false;
bool everyoneUpThree = false;
bool didAnnounceThree = false;
int countDone = 0;

// T4 vars
Semaphore *MailBoxSem = new Semaphore("mailSys", 1);
struct mailUser{
	int whoSent;
	char message[6];
	bool hasMail;
};
mailUser **myUsers;
int maxMail;
int maxMessages;
int sentNum;
int mailBoxes;

// T5 VAR
bool *gotMail;
Semaphore **myMailSem;


// this is one
void
SimpleThread(int which)
{
/*
    int num;
    
    for (num = 0; num < 5; num++) {
	printf("*** thread %d looped %d times\n", which, num);
        currentThread->Yield();
    } */
	
	int num = Random() % 5;
	
	int i = Random() % 45;
	
	printf("Shouter %d: ", which);
	switch(num)
	{
		case 0:
			printf("Brasil!\n");
			break;
		case 1:
			printf("HELP!\n");
			break;
		case 2:
			printf("Where is Brasil?\n");
			break;
		case 3:
			printf("BR? BR? BR? BR? BR? BR?\n");
			break;
		case 4:
			printf("Hakuna Matata\n");
			break;
		default:
			printf("There is no Brasil!\n");
	}
	
	while(i != 0){
		currentThread->Yield();
		i--;
	}
	
}

// This is 2

void
doEat(int myEater){
	
	proceed = true;
	doneEating = false;
	bool afterEat = true;
	int i;
	
	printf("Philosopher %d sat down\n", myEater);
	numSat++;
	didSit[myEater] = true;
	currentThread->Yield();
	
	
	for(int x = 0; x < philos; x++)
	{
		if(didSit[x] == false){
			proceed = false;
		}
		else{
			proceed = true;
		}
	}
	
	while(proceed != true){
		currentThread->Yield();
	}
	

	if(proceed == true && (numSat == philos) && doneEating != true){
		
			if(didAnnounce == false){
				printf("\n-------------------------------\n");
				printf("All Philosophers are now seated.\n");
				printf("-------------------------------\n");
				didAnnounce = true;
			}
			
		if(((isEating[(myEater+philos-1)%philos] != false) || (isEating[(myEater+1)%philos] != false))){
			while((isEating[(myEater+philos-1)%philos] != false) || (isEating[(myEater+1)%philos] != false)){
				currentThread->Yield();
			}
		}
		
			if((myEater % 2 == 0) && (isEating[myEater] == false) && (isEating[(myEater+philos-1)%philos] == false) && (isEating[(myEater+1)%philos]) == false && didEat[myEater] == false){ // even eater, not currently eating, philos to left and right are not eating and you didnt eat yet
				eatSem->P(); // crit
				isEating[myEater] = true;
				chopsticks[(myEater+1)%philos]->P();
				chopsticks[myEater]->P();
				printf("Philosopher %d picks up his right chop(%d)\n", myEater, (myEater+1)%philos);				
				printf("Philosopher %d picks up his left chop(%d)\n", myEater, myEater);			
				printf("Philosopher %d is eating\n", myEater);
				eatSem->V(); // end crit
			}
			if((myEater % 2 != 0) && (isEating[myEater] == false) && (isEating[(myEater+philos-1)%philos] == false) && (isEating[(myEater+1)%philos]) == false && didEat[myEater] == false) // odd eater, not currently eating, left and right are not eating and you didnt eat yet
			{
				eatSem->P(); // crit
				isEating[myEater] = true;
				chopsticks[myEater]->P();
				chopsticks[(myEater+1)%philos]->P();
				printf("Philosopher %d picks up his left chop(%d)\n", myEater, myEater);
				printf("Philosopher %d picks up his right chop(%d)\n", myEater, (myEater+1)%philos);
				printf("Philosopher %d is eating\n", myEater);
				eatSem->V(); // end crit
			}
		
			i = Random() % 60;
	
			while(i != 0){		// current philosopher is eating
				currentThread->Yield();
				i--;
			}
	
			if(didEat[myEater] == false){	// current philosopher is done eating
				printf("Philosopher %d puts down his left chop(%d)\n", myEater, myEater);
				chopsticks[myEater]->V();
				printf("Philosopher %d puts down his right chop(%d)\n", myEater, (myEater+1)%philos);
				chopsticks[(myEater+1)%philos]->V();
				printf("Philosopher %d is done eating\n", myEater);
				didEat[myEater] = true;
				isEating[myEater] = false;
				printf("Philosopher %d is now thinking\n", myEater);
			}
			
			for(int p = 0; p < philos; p++)
			{
				if(didEat[p] == false){
					doneEating = false;
					break;
				}
				else{
					doneEating = true;
				}
			}
			
			if(didEat[myEater] == true){
				currentThread->Yield();
			}
			
		
	}// end proceed
	
	while(doneEating != true){
		currentThread->Yield();
	}
	
	if(doneEating == true){	// everyone ate
		if(everyoneUp == false){ // not everyone up so stand up
			everyoneUp = true;
			printf("Philosopher %d is leaving the table\n", myEater);
			didStand[myEater] = true;
			for(int lp = 0; lp < philos; lp++){
				if(didStand[lp] == false){
					everyoneUp = false;
					currentThread->Yield();
				}
			}
			if(didStand[myEater] == true){
				currentThread->Yield();
			}
		}
	}	// end done eating
}

void
doThree(int myEater){/*
int threePhils;
bool *didSitThree;
bool *didEatThree;
bool *isEatingThree;
bool *didStandThree;
bool *chopsThree;
bool doneEatingThree = false;
bool didAnnounceThree = false;
int numSatThree = 0;
bool proceedThree = false;
bool everyoneUpThree = false;
bool didAnnounceThree = false;*/

	proceedThree = true;
	doneEatingThree = false;
	int myRandom;
	
	printf("Philosopher %d sat down for part 3\n", myEater);
	numSatThree++;
	didSitThree[myEater] = true;
	currentThread->Yield();
	
	
	for(int x = 0; x < philos; x++)
	{
		if(didSitThree[x] == false){
			proceedThree = false;
		}
		else{
			proceedThree = true;
		}
	}
	
	while(proceedThree != true){
		currentThread->Yield();
	}
	
	if(proceedThree == true && doneEatingThree != true){ // everyone sat down now eat and think
		if(didAnnounceThree == false){
			printf("\n---------------------------------------------\n");
			printf("All Philosophers are now seated for part three.\n");
			printf("-----------------------------------------------\n");
			didAnnounceThree = true;
		}
		
		if(((isEatingThree[(myEater+threePhils-1)%threePhils] != false) || (isEatingThree[(myEater+1)%threePhils] != false))){
			while((isEatingThree[(myEater+threePhils-1)%threePhils] != false) || (isEatingThree[(myEater+1)%threePhils] != false)){
				currentThread->Yield();
			}
		}
		
		if((myEater % 2 == 0) && (isEatingThree[myEater] == false) && ((isEatingThree[(myEater+threePhils-1)%threePhils] == false) && (isEatingThree[(myEater+1)%threePhils] == false)) && didEatThree[myEater] == false){
			while((chopsThree[(myEater+threePhils-1)%threePhils] == true) || (chopsThree[(myEater+1)%threePhils] == true) || critical == true){
				currentThread->Yield();
			}
			critical = true;
			isEatingThree[myEater] = true;
			chopsThree[(myEater+1)%threePhils] = true;
			chopsThree[myEater] = true;
			printf("Philosopher %d picks up his right chop(%d)\n", myEater, (myEater+1)%threePhils);				
			printf("Philosopher %d picks up his left chop(%d)\n", myEater, myEater);			
			printf("Philosopher %d is eating\n", myEater);
			critical = false;
		}
		
		if((myEater % 2 != 0) && (isEatingThree[myEater] == false) && ((isEatingThree[(myEater+threePhils-1)%threePhils] == false) && (isEatingThree[(myEater+1)%threePhils] == false)) && didEatThree[myEater] == false){
			while((chopsThree[(myEater+threePhils-1)%threePhils] == true) || (chopsThree[(myEater+1)%threePhils] == true) || critical == true){
				currentThread->Yield();
			}
			critical = true;
			isEatingThree[myEater] = true;
			chopsThree[myEater] = true;
			chopsThree[(myEater+1)%threePhils] = true;
			printf("Philosopher %d picks up his right chop(%d)\n", myEater, (myEater+1)%threePhils);				
			printf("Philosopher %d picks up his left chop(%d)\n", myEater, myEater);			
			printf("Philosopher %d is eating\n", myEater);
			critical = false;
		}
		
		myRandom = Random() % 60;
		
		while(myRandom != 0){		// Let the bro EAT!!!!!!!!!!!!!!
			currentThread->Yield();
			myRandom--;
		}
		
		if(didEatThree[myEater] == false){	// if u didnt finish eating yet, and u are currently eating
			while(critical == true){
				currentThread->Yield();
			}
			critical = true;
			chopsThree[myEater] = false;
			chopsThree[(myEater+1)%threePhils] = false;
			printf("Philosopher %d puts down his left chop(%d)\n", myEater, myEater);
			printf("Philosopher %d puts down his right chop(%d)\n", myEater, (myEater+1)%threePhils);
			printf("Philosopher %d is done eating\n", myEater);
			didEatThree[myEater] = true;
			isEatingThree[myEater] = false;
			printf("Philosopher %d is now thinking\n", myEater);
			critical = false;
			countDone++;
		}		
		
		for(int p = 0; p < philos; p++)
		{
			if(didEatThree[p] == false){
				doneEatingThree = false;
				break;
			}
			else{
				doneEatingThree = true;
			}
		}
			
		if(didEatThree[myEater] == true){
			currentThread->Yield();
		}
		
	} // end of eating
	
	
	if(didStandThree[myEater] == false){	
		//if(everyoneUpThree == false){ // not everyone up so stand up
			everyoneUpThree = true;
			printf("Philosopher %d is leaving the table\n", myEater);
			didStandThree[myEater] = true;
			for(int lp = 0; lp < philos; lp++){
				if(didStandThree[lp] == false){
					everyoneUpThree = false;
					currentThread->Yield();
				}
			}
			if(didStandThree[myEater] == true){
				currentThread->Yield();
			}
		//}
	}	// end done eating
}

/*	 DIS b da vars i use 
Semaphore *MailBoxSem = new Semaphore("mailSys", 1);
struct mailUser{
	int whoSent;
	char message[5];
	bool hasMail;
};
mailUser **myUsers;
int maxMail;
int maxMessages;
int sentNum;
int mailBoxes;
*/
void
doFour(int mailing){
		char brasilian[6];
		int i = 0;
		int waitRead = 0;
		int workTime = 0;
		int recep = 0;
		int mNum = 0;
		int letter = 0;
		bool didSend = false;
if(myFlag == 4){
	while(sentNum < maxMessages){

		letter = Random() % 5; // what to say
		bool doSend = true;
		printf("Person %d is checking for mail at the office\n", mailing);
		MailBoxSem->P(); // dis b da semaFoAR
		while(myUsers[mailing][i].hasMail == true && (i < maxMail)){
			printf("Person %d letter %d says %s\n", mailing, i, myUsers[mailing][i].message);
			myUsers[mailing][i].hasMail = false;
			waitRead = Random() % 60;
			if((i+1) < maxMail){
				if(myUsers[mailing][i+1].hasMail == true){ // still has mail
					while(waitRead > 0){
						currentThread->Yield();
						waitRead--;
					}
				} 	// end of still has mail
			} 		// end of checking to see that you are not greater than the max number of mail
			i++;
		}
		MailBoxSem->V();
	
		// this is where u send the mail
		if(sentNum < maxMessages){
			didSend = false;
			while(didSend == false){
				recep = Random() % mailBoxes;
				if(recep == mailing){
					recep = (recep+1)%mailBoxes;
				}

				for(int x = 0; x < maxMail; x++){
					if(myUsers[recep][x].hasMail == false && (sentNum < maxMessages)){	// if the bro has no mail give him some
						printf("Person %d is sending mail to %d\n", mailing, recep);
					//	printf("Number of sent mail is %d\n", sentNum);
						sentNum++;
						didSend = true;						
						switch(letter){		// say it
							case 0:
								sprintf(myUsers[recep][x].message, "Lemon");
								myUsers[recep][x].hasMail = true;
								break;
							case 1:
								sprintf(myUsers[recep][x].message, "Apple");
								myUsers[recep][x].hasMail = true;
								break;
							case 2:
								sprintf(myUsers[recep][x].message, "SOUR");
								myUsers[recep][x].hasMail = true;
								break;
							case 3:
								sprintf(myUsers[recep][x].message, "Brasil");
								myUsers[recep][x].hasMail = true;
								break;
							case 4:
								sprintf(myUsers[recep][x].message, "JAJAJA");
								myUsers[recep][x].hasMail = true;
								break;
							default:
								sprintf(myUsers[recep][x].message, "Ben!");
								myUsers[recep][x].hasMail = true;
						} // end o da switch
						currentThread->Yield();
					} // end of the given mail
				}
				
				if(didSend == false && (sentNum < maxMessages)){	// you didnt send anything bro
					while(myUsers[recep][0].hasMail == true){ // while you are waiting for the bro to	
						currentThread->Yield();				  // check his mail
						if(sentNum >= maxMessages){
							doSend = false;
							break;
						}
					}
					didSend = true;
					if(doSend == true){
					printf("Person %d is sending mail to %d\n", mailing, recep);	
					sentNum++;
						switch(letter){		// say it
							case 0:
								myUsers[recep][0].whoSent = mailing;
								sprintf(myUsers[recep][0].message, "Lemon");
								myUsers[recep][0].hasMail = true;
								break;
							case 1:
								myUsers[recep][0].whoSent = mailing;
								sprintf(myUsers[recep][0].message, "Apple");
								myUsers[recep][0].hasMail = true;
								break;
							case 2:
								myUsers[recep][0].whoSent = mailing;
								sprintf(myUsers[recep][0].message, "SOUR");
								myUsers[recep][0].hasMail = true;
								break;
							case 3:
								myUsers[recep][0].whoSent = mailing;
								sprintf(myUsers[recep][0].message, "Brasil");
								myUsers[recep][0].hasMail = true;
								break;
							case 4:
								myUsers[recep][0].whoSent = mailing;
								sprintf(myUsers[recep][0].message, "JAJAJA");
								myUsers[recep][0].hasMail = true;
								break;
							default:
								myUsers[recep][0].whoSent = mailing;
								sprintf(myUsers[recep][0].message, "Ben!");
								myUsers[recep][0].hasMail = true;
						} // end o da switch
						currentThread->Yield();
					}// do send is true
				} // end of you didnt send anything
			}
		}
	
		// go back to work for some random amount of time
		workTime = Random() % 75;
		while(workTime > 0){
			currentThread->Yield();
			workTime--;
		}
		// loop this until max number of messages that can be sent has been reached
	}
} // end of Flag 4

if(myFlag == 5){
	while(sentNum < maxMessages){

		letter = Random() % 5; // what to say
		bool doSend = true;
		printf("Person %d is checking for mail at the office\n", mailing);
		MailBoxSem->P(); // dis b da semaFoAR
		while(myUsers[mailing][i].hasMail == true && (i < maxMail)){
			if(gotMail[mailing] == true){
				myMailSem[recep]->V();
			}
			printf("Person %d letter %d says %s\n", mailing, i, myUsers[mailing][i].message);
			myUsers[mailing][i].hasMail = false;
			waitRead = Random() % 60;
			if((i+1) < maxMail){
				if(myUsers[mailing][i+1].hasMail == true){ // still has mail
					while(waitRead > 0){
						currentThread->Yield();
						waitRead--;
					}
				} 	// end of still has mail
			} 		// end of checking to see that you are not greater than the max number of mail
			i++;
		}
		MailBoxSem->V();
	
		// this is where u send the mail
		if(sentNum < maxMessages){
			didSend = false;
			while(didSend == false){
				recep = Random() % mailBoxes;
				if(recep == mailing){
					recep = (recep+1)%mailBoxes;
				}

				for(int x = 0; x < maxMail; x++){
					if(myUsers[recep][x].hasMail == false && (sentNum < maxMessages)){	// if the bro has no mail give him some
						printf("Person %d is sending mail to %d\n", mailing, recep);
					//	printf("Number of sent mail is %d\n", sentNum);
						sentNum++;
						didSend = true;
						gotMail[recep] = true;
						switch(letter){		// say it
							case 0:
								myMailSem[recep]->P();
								sprintf(myUsers[recep][x].message, "Lemon");
								myUsers[recep][x].hasMail = true;
								break;
							case 1:
								myMailSem[recep]->P();
								sprintf(myUsers[recep][x].message, "Apple");
								myUsers[recep][x].hasMail = true;
								break;
							case 2:
								myMailSem[recep]->P();
								sprintf(myUsers[recep][x].message, "SOUR");
								myUsers[recep][x].hasMail = true;
								break;
							case 3:
								myMailSem[recep]->P();
								sprintf(myUsers[recep][x].message, "Brasil");
								myUsers[recep][x].hasMail = true;
								break;
							case 4:
								myMailSem[recep]->P();
								sprintf(myUsers[recep][x].message, "JAJAJA");
								myUsers[recep][x].hasMail = true;
								break;
							default:
								myMailSem[recep]->P();
								sprintf(myUsers[recep][x].message, "Ben!");
								myUsers[recep][x].hasMail = true;
						} // end o da switch
						currentThread->Yield();
					} // end of the given mail
				}
				
				if(didSend == false && (sentNum < maxMessages)){	// you didnt send anything bro
					while(myUsers[recep][0].hasMail == true){ // while you are waiting for the bro to	
						currentThread->Yield();				  // check his mail
						if(sentNum >= maxMessages){
							doSend = false;
							break;
						}
					}
					didSend = true;
					if(doSend == true){
					printf("Person %d is sending mail to %d\n", mailing, recep);	
					gotMail[recep] = true;
					sentNum++;
						switch(letter){		// say it
							case 0:
								myMailSem[recep]->P();
								myUsers[recep][0].whoSent = mailing;
								sprintf(myUsers[recep][0].message, "Lemon");
								myUsers[recep][0].hasMail = true;
								break;
							case 1:
								myMailSem[recep]->P();
								myUsers[recep][0].whoSent = mailing;
								sprintf(myUsers[recep][0].message, "Apple");
								myUsers[recep][0].hasMail = true;
								break;
							case 2:
								myMailSem[recep]->P();
								myUsers[recep][0].whoSent = mailing;
								sprintf(myUsers[recep][0].message, "SOUR");
								myUsers[recep][0].hasMail = true;
								break;
							case 3:
								myMailSem[recep]->P();
								myUsers[recep][0].whoSent = mailing;
								sprintf(myUsers[recep][0].message, "Brasil");
								myUsers[recep][0].hasMail = true;
								break;
							case 4:
								myMailSem[recep]->P();
								myUsers[recep][0].whoSent = mailing;
								sprintf(myUsers[recep][0].message, "JAJAJA");
								myUsers[recep][0].hasMail = true;
								break;
							default:
								myMailSem[recep]->P();
								myUsers[recep][0].whoSent = mailing;
								sprintf(myUsers[recep][0].message, "Ben!");
								myUsers[recep][0].hasMail = true;
						} // end o da switch
						currentThread->Yield();
					}// do send is true
				} // end of you didnt send anything
			}
		}
	
		// go back to work for some random amount of time
		workTime = Random() % 75;
		while(workTime > 0){
			currentThread->Yield();
			workTime--;
		}
		// loop this until max number of messages that can be sent has been reached
	}
} // end of Flag = 5	

} // end of doing four


//----------------------------------------------------------------------
// ThreadTest
// 	Invoke a test routine.
//----------------------------------------------------------------------

void
ThreadTest()
{
	int numThreads = 0;
	int numShouts = 0;
	int numPhilos = 0;
	int numMeals = 0;
	char id[6];
	int threePhilos = 0;
	int threeMeals = 0;
	int numUsers = 0;
	int numMessages = 0;
	int numCanSend = 0;
	sentNum = 0;
	char mess[5];
	
	Thread* t;
	

    DEBUG('t', "Entering ThreadTest");

switch(myFlag){	

case 1:

	printf("---------------------TASK1---------------------------\n");
	printf("How many randomly shouting threads should be created: ");
	scanf("%d", &numThreads);
	printf("How many times should each shout: ");
	scanf("%d", &numShouts);

	
	for(int i = 0; i < numThreads; i++){
		sprintf(id, "t%d", i);
		t = new Thread(id);
		t->Fork(SimpleThread, i);
	}
	
	if(numShouts != 1)
		numShouts--;
	
	for(int x = 0; x < numThreads; x++){
		for(int j = 0; j < numShouts; j++){
			SimpleThread(x);
		}
	}

	break; // break for 1

case 2:
	
	printf("---------------------TASK2---------------------------\n");
	printf("\nHow many Philosophers will be dining this evening: ");
	scanf("%d", &numPhilos);
	printf("How many meals do we have to offer: ");
	scanf("%d", &numMeals);
	
	chopsticks = new Semaphore*[numPhilos];
	
	philos = numPhilos;
	didSit = new bool[numPhilos];
	didEat = new bool[numPhilos];
	isEating = new bool[numPhilos];
	didStand = new bool[numPhilos];
	
	for(int count = 0; count < numPhilos; count++){
		didSit[count] = false;
		didEat[count] = false;
		isEating[count] = false;
		didStand[count] = false;
	}
	
	
	for(int m = 0; m < numPhilos; m++){
		sprintf(id, "Sem%d", m);
		chopsticks[m] = new Semaphore(id, 1);
	}
	

	
	
	for(int p = 0; p < numPhilos; p++){
		sprintf(id, "Eat%d", p);
		t = new Thread(id);
		t->Fork(doEat, p);
	}

break; // break for 2
	
case 3:	

	// if myFlag == 3
	printf("---------------------TASK3---------------------------\n");
	printf("\nHow many Philosophers will be dining this evening: ");
	scanf("%d", &threePhilos);
	printf("How many meals do we have to offer: ");
	scanf("%d", &threeMeals);
		
		threePhils = threePhilos;
		
		didSitThree = new bool[threePhilos];
		didEatThree = new bool[threePhilos];
		isEatingThree = new bool[threePhilos];
		didStandThree = new bool[threePhilos];
		chopsThree = new bool[threePhilos];

	for(int h = 0; h < threePhilos; h++){
		didSitThree[h] = false;
		didEatThree[h] = false;
		isEatingThree[h] = false;
		didStandThree[h] = false;
		chopsThree[h] = false;
	}
	
	for(int j = 0; j < threePhilos; j++){
		sprintf(id, "noS%d", j);
		t = new Thread(id);
		t->Fork(doThree, j);
	} 
	
break; // break for 3
	
case 4:
	printf("---------------------TASK4---------------------------\n");
	printf("Number of mailboxes(USERS):");
	scanf("%d", &numUsers);
	printf("How many messages can each box hold: ");
	scanf("%d", &numMessages);
	printf("How many messages to send before terminating: ");
	scanf("%d", &numCanSend);
	
	myUsers = new mailUser*[numUsers];
	
	mailBoxes = numUsers;
	maxMail = numMessages;
	maxMessages = numCanSend;
	
	
	for(int g = 0; g < numUsers; g++){
		myUsers[g] = new mailUser[numMessages];
		myUsers[g][0].hasMail = false;
	}
	myUsers[0][0].hasMail = true;
	//myUsers[0][0].message = "cats";
	sprintf(myUsers[0][0].message, "cats");
	
	for(int p = 0; p < numUsers; p++){
		sprintf(id, "m%d", p);
		t = new Thread(id);
		t->Fork(doFour, p);
	}
	break; // break for 4
	
case 5:
	printf("---------------------TASK5---------------------------\n");
	printf("Number of mailboxes(USERS):");
	scanf("%d", &numUsers);
	printf("How many messages can each box hold: ");
	scanf("%d", &numMessages);
	printf("How many messages to send before terminating: ");
	scanf("%d", &numCanSend);
	myMailSem = new Semaphore*[numUsers];
	
	for(int ariba = 0; ariba < numUsers; ariba++){
		sprintf(id, "CAR%d", ariba);
		myMailSem[ariba] = new Semaphore(id, numMessages);
	}
	gotMail = new bool[numUsers];
	myUsers = new mailUser*[numUsers];
	
	mailBoxes = numUsers;
	maxMail = numMessages;
	maxMessages = numCanSend;
	
	
	for(int gk = 0; gk < numUsers; gk++){
		myUsers[gk] = new mailUser[numMessages];
		myUsers[gk][0].hasMail = false;
		gotMail[gk] = false;
	}
	myUsers[0][0].hasMail = true;
	//myUsers[0][0].message = "cats";
	sprintf(myUsers[0][0].message, "cats");
	
	for(int pf = 0; pf < numUsers; pf++){
		sprintf(id, "m%d", pf);
		t = new Thread(id);
		t->Fork(doFour, pf);
	}	

break; // break for 5

default:
		printf("Improper input, process now terminating\n");
	
} // end switch
	
}
